//Header file definition for 3x3 matrix
//Lambda - Global Illumination Renderer

#ifndef __MATRIX3_H__
#define __MATRIX3_H__

#pragma once
#include "Vector.h"
#include<iostream>

class Matrix3
{
public:
	// 3x3 matrix
	float m00, m01, m02;
	float m10, m11, m12;
	float m20, m21, m22;

	//constructor
	Matrix3();
	Matrix3(float _m00, float _m01, float _m02,
			float _m10, float _m11, float _m12,
			float _m20, float _m21, float _m22);

	//construct a matrix from 3 vectors
	//with each vector forming one row
	void MatrixFromRow(Vector3& V0, Vector3& V1, Vector3& V2);		
	
	//construct a matrix from 3 vectors column wise
	void MatrixFromCol(Vector3& V0, Vector3& V1, Vector3& V2);

	//operators
	Matrix3 operator - ();
	Matrix3 operator + (Matrix3& M);
	Matrix3 operator - (Matrix3& M);
	Matrix3 operator * (Matrix3& M);
	Vector3 operator * (Vector3& V);
	friend Vector3 operator * (Vector3& V, Matrix3& M)
	{
		return Vector3(M.m00*V.x+M.m01*V.y+M.m02*V.z, M.m01*V.x+M.m11*V.y+M.m21*V.z, M.m02*V.x+M.m12*V.y+M.m22*V.z);
	}
	Matrix3 operator / (float k);
	Matrix3 operator * (float k);
	
	//other misc functions
	
	//Get a new transposed matrix from the current matrix
	Matrix3 GetTransposedMatrix();

	//Transpose the current matrix
	void TransposeMatrix();

	//Determinant of matrix
	float Determinant();

	//Adjacency matrix
	Matrix3 GetAdjMatrix();

	//Get the inverse matrix of the given matrix
	bool GetInverse(Matrix3& ipMatrix);

	//Output to a stream
	friend void operator << (std::ostream& op, Matrix3& M)
	{
		op<<M.m00<<" "<<M.m01<<" "<<M.m02<<"\n";
		op<<M.m10<<" "<<M.m11<<" "<<M.m12<<"\n";
		op<<M.m20<<" "<<M.m21<<" "<<M.m22<<"\n";
	}
};

#endif